
package de.uni.wuppertal.server.ui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.ServerSocket;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import de.uni.wuppertal.server.ErrorLogEntry;
import de.uni.wuppertal.server.ServerInfo;
import de.uni.wuppertal.server.ftp.FTPServer;
import de.uni.wuppertal.server.http.HTTPServer;
import de.uni.wuppertal.server.util.Resource;

/**
 * @author Martin Schröder
 * @author Patrik Nordsiek
 */
public class AddServerDialog extends JDialog
{
	private static final String FTP_SERVER = "FTP-Server";
	private static final String HTTP_SERVER = "HTTP-Server";
	
	private static final long serialVersionUID = 1L;
	
	private static final int ERROR_NAME = 1;
	private static final int ERROR_PORT = 2;
	private static final int ERROR_DIRECTORY = 4;
	
	private int error = 0;
	
	private final JPanel contentPanel = new JPanel();
	private JTextField nameTextField;
	private JTextField directoryTextField;
	
	private JButton okButton;
	
	private JButton cancelButton;
	
	private JLabel errorLabel;
	
	private JSpinner portSpinner;
	
	private JComboBox typeComboBox;
	
	private MainWindow window;
	
	/**
	 * Create the dialog.
	 */
	public AddServerDialog(MainWindow window)
	{
		super();
		
		this.window = window;
		
		createUI();
		createActionListeners();
	}
	
	private void createUI()
	{
		setTitle("Serverinstanz hinzufügen");
		setIconImage(Resource.getIcon("icon/server.png").getImage());
		setBounds(100, 100, 480, 199);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(BorderFactory.createTitledBorder("Servereinstellungen"));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		GridBagLayout gbl_contentPanel = new GridBagLayout();
		gbl_contentPanel.columnWidths = new int[]
		{
			0, 0, 0, 0, 0, 0
		};
		gbl_contentPanel.rowHeights = new int[]
		{
			0, 0, 0, 0, 0
		};
		gbl_contentPanel.columnWeights = new double[]
		{
			1.0, 1.0, 1.0, 1.0, 0.0, Double.MIN_VALUE
		};
		gbl_contentPanel.rowWeights = new double[]
		{
			0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE
		};
		contentPanel.setLayout(gbl_contentPanel);
		{
			JLabel lblTyp = new JLabel("Typ:");
			GridBagConstraints gbc_lblTyp = new GridBagConstraints();
			gbc_lblTyp.anchor = GridBagConstraints.WEST;
			gbc_lblTyp.insets = new Insets(0, 0, 5, 5);
			gbc_lblTyp.gridx = 0;
			gbc_lblTyp.gridy = 0;
			contentPanel.add(lblTyp, gbc_lblTyp);
		}
		{
			typeComboBox = new JComboBox();
			typeComboBox.setModel(new DefaultComboBoxModel(new String[]
			{
				HTTP_SERVER, FTP_SERVER
			}));
			typeComboBox.setSelectedIndex(0);
			GridBagConstraints gbc_typeComboBox = new GridBagConstraints();
			gbc_typeComboBox.gridwidth = 4;
			gbc_typeComboBox.insets = new Insets(0, 0, 5, 0);
			gbc_typeComboBox.fill = GridBagConstraints.HORIZONTAL;
			gbc_typeComboBox.gridx = 1;
			gbc_typeComboBox.gridy = 0;
			contentPanel.add(typeComboBox, gbc_typeComboBox);
		}
		{
			JLabel lblBezeichnung = new JLabel("Name:");
			GridBagConstraints gbc_lblBezeichnung = new GridBagConstraints();
			gbc_lblBezeichnung.insets = new Insets(0, 0, 5, 5);
			gbc_lblBezeichnung.anchor = GridBagConstraints.WEST;
			gbc_lblBezeichnung.gridx = 0;
			gbc_lblBezeichnung.gridy = 1;
			contentPanel.add(lblBezeichnung, gbc_lblBezeichnung);
		}
		{
			nameTextField = new JTextField();
			GridBagConstraints gbc_nameTextField = new GridBagConstraints();
			gbc_nameTextField.gridwidth = 4;
			gbc_nameTextField.fill = GridBagConstraints.HORIZONTAL;
			gbc_nameTextField.insets = new Insets(0, 0, 5, 0);
			gbc_nameTextField.gridx = 1;
			gbc_nameTextField.gridy = 1;
			contentPanel.add(nameTextField, gbc_nameTextField);
			nameTextField.setColumns(10);
		}
		{
			JLabel lblPort = new JLabel("Port:");
			GridBagConstraints gbc_lblPort = new GridBagConstraints();
			gbc_lblPort.anchor = GridBagConstraints.WEST;
			gbc_lblPort.insets = new Insets(0, 0, 5, 5);
			gbc_lblPort.gridx = 0;
			gbc_lblPort.gridy = 2;
			contentPanel.add(lblPort, gbc_lblPort);
		}
		{
			portSpinner = new JSpinner();
			portSpinner.setModel(new SpinnerNumberModel(new Integer(20000), null, null, new Integer(1)));
			GridBagConstraints gbc_portSpinner = new GridBagConstraints();
			gbc_portSpinner.fill = GridBagConstraints.HORIZONTAL;
			gbc_portSpinner.insets = new Insets(0, 0, 5, 5);
			gbc_portSpinner.gridx = 1;
			gbc_portSpinner.gridy = 2;
			contentPanel.add(portSpinner, gbc_portSpinner);
		}
		{
			JLabel lblVerzeichnis = new JLabel("Verzeichnis:");
			GridBagConstraints gbc_lblVerzeichnis = new GridBagConstraints();
			gbc_lblVerzeichnis.anchor = GridBagConstraints.WEST;
			gbc_lblVerzeichnis.insets = new Insets(0, 0, 0, 5);
			gbc_lblVerzeichnis.gridx = 0;
			gbc_lblVerzeichnis.gridy = 3;
			contentPanel.add(lblVerzeichnis, gbc_lblVerzeichnis);
		}
		{
			directoryTextField = new JTextField();
			GridBagConstraints gbc_directoryTextField = new GridBagConstraints();
			gbc_directoryTextField.gridwidth = 4;
			gbc_directoryTextField.insets = new Insets(0, 0, 0, 5);
			gbc_directoryTextField.fill = GridBagConstraints.HORIZONTAL;
			gbc_directoryTextField.gridx = 1;
			gbc_directoryTextField.gridy = 3;
			contentPanel.add(directoryTextField, gbc_directoryTextField);
			directoryTextField.setColumns(10);
		}
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setBorder(new EmptyBorder(5, 5, 5, 5));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			GridBagLayout gbl_buttonPane = new GridBagLayout();
			gbl_buttonPane.columnWidths = new int[]
			{
				0, 0, 0, 0
			};
			gbl_buttonPane.rowHeights = new int[]
			{
				0, 0
			};
			gbl_buttonPane.columnWeights = new double[]
			{
				1.0, 0.0, 0.0, Double.MIN_VALUE
			};
			gbl_buttonPane.rowWeights = new double[]
			{
				0.0, Double.MIN_VALUE
			};
			buttonPane.setLayout(gbl_buttonPane);
			{
				errorLabel = new JLabel("");
				errorLabel.setForeground(Color.RED);
				GridBagConstraints gbc_errorLabel = new GridBagConstraints();
				gbc_errorLabel.anchor = GridBagConstraints.WEST;
				gbc_errorLabel.insets = new Insets(0, 0, 0, 5);
				gbc_errorLabel.gridx = 0;
				gbc_errorLabel.gridy = 0;
				buttonPane.add(errorLabel, gbc_errorLabel);
			}
			{
				okButton = new JButton("OK");
				okButton.setEnabled(false);
				GridBagConstraints gbc_okButton = new GridBagConstraints();
				gbc_okButton.insets = new Insets(0, 0, 0, 5);
				gbc_okButton.gridx = 1;
				gbc_okButton.gridy = 0;
				buttonPane.add(okButton, gbc_okButton);
			}
			{
				cancelButton = new JButton("Abbrechen");
				GridBagConstraints gbc_cancelButton = new GridBagConstraints();
				gbc_cancelButton.gridx = 2;
				gbc_cancelButton.gridy = 0;
				buttonPane.add(cancelButton, gbc_cancelButton);
			}
		}
	}
	
	private void createActionListeners()
	{
		nameTextField.addKeyListener(new KeyAdapter()
		{
			@Override
			public void keyReleased(KeyEvent event)
			{
				if(nameTextField.getText().length() > 0)
				{
					removeError(ERROR_NAME);
				}
				else
				{
					addError(ERROR_NAME, "Kein Name angegeben");
				}
			}
		});
		
		portSpinner.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent event)
			{
				int port = Integer.valueOf(portSpinner.getValue().toString());
				
				if(window.getManager().isPortInUse(port))
				{
					addError(ERROR_PORT, "Port wird bereits verwendet");
				}
				else
				{
					try
					{
						ServerSocket socket = new ServerSocket(port);
						socket.close();
						
						removeError(ERROR_PORT);
					}
					catch(Throwable e)
					{
						addError(ERROR_PORT, "Port wird bereits verwendet");
					}
				}
			}
		});
		
		directoryTextField.addKeyListener(new KeyAdapter()
		{
			@Override
			public void keyReleased(KeyEvent event)
			{
				File file = new File(directoryTextField.getText());
				
				if(file.isDirectory())
				{
					removeError(ERROR_DIRECTORY);
				}
				else
				{
					addError(ERROR_DIRECTORY, "Ungültiges Verzeichnis ausgewählt");
				}
			}
		});
		
		okButton.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				ServerInfo server;
				
				if(((String)typeComboBox.getSelectedItem()).equals(HTTP_SERVER))
				{
					server = new HTTPServer();
				}
				else
				{
					server = new FTPServer();
				}
				
				server.setName(nameTextField.getText());
				server.setPort(Integer.valueOf(portSpinner.getValue().toString()));
				server.setRootDirectory(directoryTextField.getText());
				
				try
				{
					window.addServer(server);
				}
				catch(Throwable e)
				{
					window.log(new ErrorLogEntry(e));
				}
				
				dispose();
			}
		});
		
		cancelButton.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				dispose();
			}
		});
	}
	
	private synchronized void addError(int flag, String message)
	{
		errorLabel.setText(message);
		
		error |= flag;
		
		okButton.setEnabled(false);
	}
	
	private synchronized void removeError(int flag)
	{
		error = (error | flag) ^ flag;
		
		if(error < 1)
		{
			errorLabel.setText("");
			
			okButton.setEnabled(true);
		}
	}
}
